package com.example.apartment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.apartment.common.RespException;
import com.example.apartment.common.RespExceptionEnum;
import com.example.apartment.domain.*;
import com.example.apartment.mapper.BedMapper;
import com.example.apartment.mapper.BuildingMapper;
import com.example.apartment.mapper.RoomMapper;
import com.example.apartment.mapper.StudentMapper;
import com.example.apartment.service.BedService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 床位信息业务层实现类
 *
 * @author wuzexin
 * @date 2021/11/2 17:03
 */
@Service
public class BedServiceImpl implements BedService {

    @Resource
    private BedMapper bedMapper;
    @Resource
    private BuildingMapper buildingMapper;
    @Resource
    private RoomMapper roomMapper;
    @Resource
    private StudentMapper studentMapper;

    /*
        判断管理员是否拥有权限
        role: 1-系统管理员 2-宿舍楼管理员 3-未审核不可登录状态
        只有系统管理员和对应楼栋的宿舍楼管理员才有权限进行操作
     */

    /**
     * 创建床位
     *
     * @param admin        管理员信息
     * @param bedNum       床位号
     * @param roomNum      宿舍号
     * @param buildingName 宿舍楼名字
     * @return 返回床位信息
     */
    @Override
    public Bed create(Admin admin, Integer bedNum, Integer roomNum, String buildingName) {

        // 判断宿舍楼是否存在
        QueryWrapper buildingQueryWraper = new QueryWrapper();
        buildingQueryWraper.eq("building_name", buildingName);
        Building building = buildingMapper.selectOne(buildingQueryWraper);

        // 如果宿舍楼不存在，抛出异常
        if (building == null) {
            throw new RespException(RespExceptionEnum.BUILDING_NOT_EXISTS);
        }

        Integer buildingId = building.getId();

        // 判断用户是否为系统管理员 或者为该楼栋的宿舍管理员
        if ((admin.getRole() != 1) && !(admin.getRole() == 2 && admin.getBuildingId().equals(buildingId))) {
            // 不是则抛出权限不够异常
            throw new RespException(RespExceptionEnum.NEED_PERMISSIONS);
        }

        // 判断宿舍号是否存在
        QueryWrapper roomQueryWrapper = new QueryWrapper();
        roomQueryWrapper.eq("building_id", buildingId);
        roomQueryWrapper.eq("room_num", roomNum);
        Room room = roomMapper.selectOne(roomQueryWrapper);

        // 如果room不存在，则抛出异常
        if (room == null) {
            throw new RespException(RespExceptionEnum.ROOM_NOT_EXISTS);
        }

        Integer roomId = room.getId();

        // 判断床位号是否已经存在
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("building_id", buildingId);
        queryWrapper.eq("room_id", roomId);
        queryWrapper.eq("bed_num", bedNum);
        Bed bed1 = bedMapper.selectOne(queryWrapper);

        // 如果存在，则抛出异常
        if (bed1 != null) {
            throw new RespException(RespExceptionEnum.BED_NUM_EXISTS);
        }

        // 实例化一个bed对象
        Bed bed = new Bed();
        bed.setBuildingId(buildingId);
        bed.setRoomId(roomId);
        bed.setBedNum(bedNum);

        int insert = bedMapper.insert(bed);

        // 如果insert==0，抛出新增失败异常
        if(insert == 0) {
            throw new RespException(RespExceptionEnum.INSERT_FAILED);
        }

        return bed;
    }


    /**
     * 修改宿舍床号
     *
     * @param admin  管理员用户信息
     * @param id     床位id
     * @param bedNum 床号
     * @return
     */
    @Override
    public Bed update(Admin admin, Integer id, Integer bedNum) {

        // 获得该床位号所对应的楼栋id
        Bed bed = bedMapper.selectById(id);

        // 判断用户是否为系统管理员 或者为该楼栋的宿舍管理员
        if ((admin.getRole() != 1) && !(admin.getRole() == 2 && admin.getBuildingId().equals(bed.getBuildingId()))) {
            // 不是则抛出权限不够异常
            throw new RespException(RespExceptionEnum.NEED_PERMISSIONS);
        }

        // 判断床位号码是否重名
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("building_id", bed.getBuildingId());
        queryWrapper.eq("room_id", bed.getRoomId());
        queryWrapper.eq("bed_num", bedNum);
        Bed bed1 = bedMapper.selectOne(queryWrapper);
        if (bed1 != null) {
            // 如果该宿舍存在同一床位号，则抛出异常
            throw new RespException(RespExceptionEnum.BED_NUM_EXISTS);
        }

        // 更新数据库
        bed.setBedNum(bedNum);
        int update = bedMapper.updateById(bed);

        // 如果update不为1，则抛出更新失败异常
        if (update != 1) {
            throw new RespException(RespExceptionEnum.UPDATE_FAILED);
        }

        return bed;
    }

    /**
     * 删除宿舍床号
     *
     * @param admin 管理员用户信息
     * @param id    床位id
     */
    @Override
    public void delete(Admin admin, Integer id) {

        // 获得该床位号所对应的楼栋id
        Bed bed = bedMapper.selectById(id);

        // 判断用户是否为系统管理员 或者为该楼栋的宿舍管理员
        if ((admin.getRole() != 1) && !(admin.getRole() == 2 && admin.getBuildingId().equals(bed.getBuildingId()))) {
            // 不是则抛出权限不够异常
            throw new RespException(RespExceptionEnum.NEED_PERMISSIONS);
        }

        // 判断该床位是否有学生居住
        QueryWrapper stuQueryWrapper = new QueryWrapper();
        stuQueryWrapper.eq("bed_id", id);
        Student student = studentMapper.selectOne(stuQueryWrapper);
        if (student != null) {
            // 如有学生住，则抛出床位非空异常
            throw new RespException(RespExceptionEnum.BED_NOT_EMPTY);
        }

        // 操作数据库
        int delete = bedMapper.deleteById(id);

        // 如果delete不为1，则抛出删除失败异常
        if (delete != 1) {
            throw new RespException(RespExceptionEnum.DELETE_FAILED);
        }
    }

    /**
     * 查询所有床位信息
     *
     * @param admin 管理员用户信息
     * @return
     */
    @Override
    public List<Bed> select(Admin admin) {

        // 查询管理员权限登记  1-系统管理员  2-宿舍管理员
        int role = admin.getRole();

        List<Bed> list = null;

        if (role == 1) {
            // 系统管理员能查询所有床位信息
            list = bedMapper.selectList(null);
        } else if (role == 2) {
            // 宿舍管理员只能查询自己所负责宿舍楼的床位信息
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("building_id", admin.getBuildingId());
            list = bedMapper.selectList(queryWrapper);
        } else {
            // 抛出无权限异常
            throw new RespException(RespExceptionEnum.NEED_PERMISSIONS);
        }

        for (Bed bed : list) {

            // 通过roomId 获取 roomNum
            Room room = roomMapper.selectById(bed.getRoomId());
            Integer roomNum = room.getRoomNum();

            // 通过buildingId 获取 BuildingName
            Building building = buildingMapper.selectById(bed.getBuildingId());
            String buildingName = building.getBuildingName();

            bed.setRoomNum(roomNum);
            bed.setBuildingName(buildingName);
        }
        return list;
    }

    /**
     * 根据buildingName查询所有床位信息
     *
     * @param admin
     * @param buildingName
     * @return
     */
    @Override
    public List<Bed> selectByBuildingName(Admin admin, String buildingName) {

        // 根据buildingName获取宿舍楼信息
        QueryWrapper buildingQueryWrapper = new QueryWrapper();
        buildingQueryWrapper.eq("building_name", buildingName);
        Building building = buildingMapper.selectOne(buildingQueryWrapper);

        // 判断宿舍楼是否存在
        if (building == null) {
            // 如果不存在，则抛出异常
            throw new RespException(RespExceptionEnum.BUILDING_NOT_EXISTS);
        }

        // 判断用户是否为系统管理员 或者为该楼栋的宿舍管理员
        if ((admin.getRole() != 1) && !(admin.getRole() == 2 && admin.getBuildingId().equals(building.getId()))) {
            // 不是则抛出权限不够异常
            throw new RespException(RespExceptionEnum.NEED_PERMISSIONS);
        }

        // 根据buildingId，获取宿舍楼所有床位信息
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("building_id", building.getId());
        List<Bed> list = bedMapper.selectList(queryWrapper);

        // 遍历List
        for (Bed bed : list) {
            // 查询buildingName，添加到bed中
            Building build = buildingMapper.selectById(bed.getBuildingId());
            bed.setBuildingName(build.getBuildingName());

            // 查询roomNum，添加到bed中
            Room room = roomMapper.selectById(bed.getRoomId());
            bed.setRoomNum(room.getRoomNum());

            // 查询学生信息，添加到bed中
            QueryWrapper stuQueryWrapper = new QueryWrapper();
            stuQueryWrapper.eq("bed_id", bed.getId());
            Student stu = studentMapper.selectOne(stuQueryWrapper);
            if (stu != null) {
                bed.setName(stu.getName());
                bed.setSid(stu.getSid());
                bed.setSex(stu.getSex());
                bed.setMajor(stu.getMajor());
                bed.setClassroom(stu.getClassroom());
                bed.setCellphone(stu.getCellphone());
            }
        }

        // 返回床位列表
        return list;
    }
}
